/////////////////////////////////////////////////////////////////////////////
///
/// Author      : Luis M. de la Cruz Salas
/// Date        : Mon Sep  4 19:58:07 CDT 2006
/// Version     : 0.1
/// Last Rev.   : Mon Sep  4 19:58:07 CDT 2006
///
/////////////////////////////////////////////////////////////////////////////
///
/// NAME
///     ParticleTracking.h
///
/// SYNOPSIS
///     #include "ParticleTracking.h"
///
/// DESCRIPTION
///
/// DIAGNOSTICS
///
/////////////////////////////////////////////////////////////////////////////

#ifndef _PARTICLETRACKING_H_
#define _PARTICLETRACKING_H_

#include <iostream>
#include <list>
#include "Tuna.hpp"

using namespace Tuna;
using namespace std;

namespace Tuna {

//template<typename Integrator_t, int Dim>
template<typename Integrator_t>
class ParticleTracking
{
 public:

  typedef typename Typeinfo<Integrator_t>::prec_t prec_t;
  typedef typename TunaArray<prec_t, Typeinfo<Integrator_t>::Dim>::tiny floatTinyArray_t;
  typedef typename TunaArray<int, Typeinfo<Integrator_t>::Dim>::tiny intTinyArray_t;
  typedef typename TunaArray<prec_t, Typeinfo<Integrator_t>::Dim>::huge ScalarField_t;

///
///  Traits to define the type of arrays to be used.
///  These definitions depends on the dimension of the problem.
///
///  floatTinyArray_t : Array of floats mostly used for deltas of meshes
///
/*
    typedef typename TunaArray<double, Dim>::tiny floatTinyArray_t;
    typedef typename TunaArray<int, Dim>::tiny intTinyArray_t;
    typedef typename TunaArray<double, Dim>::huge ScalarField_t;
*/      
    ParticleTracking() { };
    
    ~ParticleTracking() { };

    inline floatTinyArray_t track(floatTinyArray_t &pos,
				  const floatTinyArray_t &deltas,
				  ScalarField_t &u,
				  ScalarField_t &v,
				  prec_t dt)
	{
	    /// Location, Interpolation and Integration
	    return ( newPos = f_object.integrate(pos, deltas, u, v, dt) );
	}

    inline floatTinyArray_t track(floatTinyArray_t &pos,
				  const floatTinyArray_t &deltas,
				  ScalarField_t &u,
				  ScalarField_t &v,
				  ScalarField_t &w,
				  prec_t dt)
	{
	    /// Location, Interpolation and Integration
	    return ( newPos = f_object.integrate(pos, deltas, u, v, w, dt) );
	}

    inline floatTinyArray_t track(floatTinyArray_t &pos,
				  const floatTinyArray_t &deltas,
				  ScalarField_t &u,
				  ScalarField_t &v,
				  ScalarField_t &unext,
				  ScalarField_t &vnext,
				  prec_t dt)
	{
	    /// Location, Interpolation and Integration
	    return ( newPos = f_object.integrate(pos, deltas,
						 u, v, unext,
						 vnext, dt) );
	}
///---------------------------------------------------------------------
/// This is a R-K 4 version for particle traking with respect to vortex
///
    
    inline floatTinyArray_t track(floatTinyArray_t &pos,
				  const floatTinyArray_t &deltas,
				  ScalarField_t &u,
				  ScalarField_t &v,
				  ScalarField_t &unext,
				  ScalarField_t &vnext,
				  prec_t dt,
				  floatTinyArray_t &trayvort)
	{
	    /// Location, Interpolation and Integration
	    return ( newPos = f_object.integrate(pos, deltas,
						 u, v, unext,
						 vnext, dt, trayvort) );
	}
///---------------------------------------------------------------------    
    
    inline floatTinyArray_t track(floatTinyArray_t &pos,
				  const floatTinyArray_t &deltas,
				  ScalarField_t &u,
				  ScalarField_t &v,
				  ScalarField_t &w,	  
				  ScalarField_t &unext,
				  ScalarField_t &vnext,
				  ScalarField_t &wnext,
				  prec_t dt)
	{
	    /// Location, Interpolation and Integration
	    return ( newPos = f_object.integrate(pos, deltas,
						 u, v, w,
						 unext, vnext, wnext,
						 dt) );
	}
    
 private:
    intTinyArray_t IJK;
    floatTinyArray_t UVW, ABG, newPos;
    Integrator_t f_object;
};

} // Tuna namespace

#endif /// _PARTICLETRACKING_H_
